/*
 * #%L
 * java model
 * %%
 * Copyright (C) 2009 - 2011 prefabware.com Stefan Isele
 * %%
 * All Rights Reserved.
 * This program is dual-licensed under the GNU General Public license
 * or a commercial license.
 * You may select to use one or the other of these licenses.
 * To obtain a commercial license please contact Stefan Isele at www.stefan-isele.de
 * Any modifications to this file must keep this entire header intact.
 * Redistribution, except as permitted by the selected license, is prohibited.
 * #L%
 */
package com.prefabware.jmodel.expression.literal;

import com.prefabware.jmodel.JType;
import com.prefabware.jmodel.code.JCodable;
import com.prefabware.jmodel.code.JCodeOptions;

/**
 * can be used as a value in code or an expression. <br>
 * in Java exist : IntegerLiteral, FloatingPointLiteral, BooleanLiteral,
 * CharacterLiteral, StringLiteral, NullLiteral
 * 
 * 
 * @author sisele_job
 * 
 */
public abstract class JLiteralBase<TYPE> implements JLiteral {
	/**
	 * creates a new Literal for the given object.
	 * @param object
	 * 
	 * @return if object == null, returns a NullLiteral.NullLiteral#asCode() =
	 *         null (without '') <br>
	 *         if object == 'null' returns a
	 *         StringLiteral.StringLiteral#asCode() = 'null' (with '') <br>
	 */
	public static JLiteral create(Object object) {
		if (object == null) {
			return new JNullLiteral();
		} else if (object.getClass().isArray()) {
			return new JArrayLiteral((Object[]) object, object.getClass());
		} else if (object instanceof JType) {
			return new JJTypeLiteral((JType) object);
		} else if (object instanceof Class) {
			return new JClassLiteral((Class<?>) object);
		} else if (object instanceof Enum) {
			return new JEnumLiteral((Enum<?>) object);
		} else if (object instanceof JCodable) {
			return new JCodableLiteral((JCodable) object);
		} else if (object instanceof String) {
			return new JStringLiteral((String) object);
		} else if (object instanceof Long) {
			return new JLongLiteral((Long) object);
		} else {
			return new JObjectLiteral(object.getClass(), object);
		}
	}

	private TYPE object;

	public JLiteralBase(TYPE object) {
		super();
		this.object = object;
	}

	@Override
	public TYPE getObject() {
		return object;
	}


	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((object == null) ? 0 : object.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		JLiteralBase<?> other = (JLiteralBase<?>) obj;
		if (object == null) {
			if (other.object != null)
				return false;
		} else if (!object.equals(other.object))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return this.getClass().getSimpleName()+"["+asCode(JCodeOptions.DEFAULT)+"]";
	}


}
